\myparagraph{GCC 4.8.1 с оптимизацией \Othree}
\label{gcc481_o3}

В линейке процессоров P6 от Intel 
появились новые FPU-инструкции\footnote{Начиная с Pentium Pro, Pentium-II, итд.}.
\myindex{x86!\Instructions!FUCOMI}
Это \INS{FUCOMI} (сравнить операнды и выставить флаги основного CPU) и
\myindex{x86!\Instructions!FCMOVcc}
\INS{FCMOVcc} (работает как \INS{CMOVcc}, но на регистрах FPU).
Очевидно, разработчики GCC решили отказаться от поддержки процессоров до линейки P6 (ранние Pentium, 80486, итд.).

И кстати, FPU уже давно не отдельная часть процессора в линейке P6, так что флаги основного CPU можно модифицировать из FPU.

Вот что имеем:

\lstinputlisting[caption=\Optimizing GCC 4.8.1,style=customasmx86]{patterns/12_FPU/3_comparison/x86/GCC481_O3_RU.s}

Не совсем понимаю, зачем здесь \INS{FXCH} (поменять местами операнды).

От нее легко избавиться поменяв местами инструкции \FLD либо заменив 
\INS{FCMOVBE} (\IT{below or equal}~--- меньше или равно) на 
\INS{FCMOVA} (\IT{above}~--- больше).

Должно быть, неаккуратность компилятора.

Так что \INS{FUCOMI} сравнивает \ST{0} ($a$) и \ST{1} ($b$) 
и затем устанавливает флаги основного CPU.
\INS{FCMOVBE} проверяет флаги и копирует \ST{1} 
(в тот момент там находится $b$) в 
\ST{0} (там $a$) если $ST0 (a) <= ST1 (b)$.
В противном случае ($a>b$), она оставляет $a$ в \ST{0}.

Последняя \FSTP оставляет содержимое \ST{0} на вершине стека, выбрасывая содержимое \ST{1}.

Попробуем оттрассировать функцию в GDB:

\lstinputlisting[caption=\Optimizing GCC 4.8.1 and GDB,numbers=left]{patterns/12_FPU/3_comparison/x86/gdb.txt}

Используя \q{ni}, дадим первым двум инструкциям \FLD исполниться.

Посмотрим регистры FPU (строка 33).

Как уже было указано ранее, регистры FPU это скорее кольцевой буфер, нежели стек (\myref{FPU_is_rather_circular_buffer}).
И GDB показывает не регистры \GTT{STx}, а внутренние регистры FPU (\GTT{Rx}). 
Стрелка (на строке 35) указывает на текущую вершину стека.

Вы можете также увидеть содержимое регистра \GTT{TOP} в \q{Status Word} (строка 44). Там сейчас 6, так что
вершина стека сейчас указывает на внутренний регистр 6.

Значения $a$ и $b$ меняются местами после исполнения \INS{FXCH} (строка 54).

\INS{FUCOMI} исполнилась (строка 83).
Посмотрим флаги: \CF выставлен (строка 95).

\INS{FCMOVBE} действительно скопировал значение $b$ (см. строку 104).

\FSTP оставляет одно значение на вершине стека (строка 136). 
Значение \GTT{TOP} теперь 7, так что вершина FPU-стека указывает на внутренний регистр 7.
